#include <avr/io.h>
#include <avr/interrupt.h>
#include "timer.h"




volatile unsigned long actualMillis;

volatile unsigned long _timer0_ovf_ctr;


/*
void delay_ms(unsigned char time_ms)
{
	unsigned short delay_count = F_CPU / 1000;

	unsigned short cnt;
	asm volatile ("\n"
		"L_dl1%=:\n\t"
		"mov %A0, %A2\n\t"
		"mov %B0, %B2\n"
		"L_dl2%=:\n\t"
		"sbiw %A0, 1\n\t"
		"brne L_dl2%=\n\t"
		"dec %1\n\t" "brne L_dl1%=\n\t":"=&w" (cnt)
		:"r"(time_ms), "r"((unsigned short) (delay_count))
	);
}

*/

#define CYCLES_PER_US ((F_CPU+500000)/1000000)  // cpu cycles per microsecond


void delay_us(unsigned short time_us) 
{
	unsigned short delay_loops;
	register unsigned short i;

	delay_loops = (time_us+3)/5*CYCLES_PER_US; // +3 for rounding up (dirty) 

	// one loop takes 5 cpu cycles 
	for (i=0; i < delay_loops; i++) {};
}




void timer0Init(void) {
	// Init timer0 to fire one in a mili
	// with F_CPU = 8000000 we get 8000000/256 = 31250 overflows per second
	// a milli is 1/1000 sec => 31,250 overflows per mili 
	// with 31 counts we hav an error of 2,3%
	// with a prescaler of 32 we get 8000000/256/8 = 3906,26 ticks/s => 1 ms ca= 4 ovf
	
	actualMillis = 0;
	_timer0_ovf_ctr = 0;
	TCCR0 |= ( 0 << CS02) | ( 1 << CS01 ) | (0 << CS00) ; // prescaler 8
	TCNT0 = 0; // reset tcnt
	TIMSK |= ( 1 << TOIE0); // enable TCNT0 overflow interrupt

}


/*
void timer0Reset(void) {
	//restart timer count
	TCNT0=0x00;	//clear timer
	//clear timer0's overflow counter.
	actualMillis = 0;
	_timer0_ovf_ctr = 0;
	
}
*/

/*
uint8_t timer0GetCount(void) {
	return TCNT0;
}


unsigned long timer0GetOverflow(void) {
	return _timer0_ovf_ctr;
}
*/

unsigned long timer0GetTicks(void) {
	return (((unsigned long)_timer0_ovf_ctr) << 8UL) + TCNT0;
}



void TIMER0_OVF0_vect(void) __attribute__((interrupt));
ISR(TIMER0_OVF0_vect) { 
	_timer0_ovf_ctr++;
	if ( (( _timer0_ovf_ctr >>2) << 2 ) == _timer0_ovf_ctr) // %4
		actualMillis++;
}
